package com.group01.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.group01.dto.Admin.AdminLoginDTO;
import com.group01.enums.CodeAndMessageEnum;
import com.group01.mapper.AdminMapper;
import com.group01.pojo.User;
import com.group01.result.Result;
import com.group01.service.AdminService;
import com.group01.utils.AESUtil;
import com.group01.utils.BeanCopyUtils;
import com.group01.utils.CommonUtils;
import com.group01.utils.JwtUtil;
import com.group01.vo.Admin.AdminLoginVO;
import com.group01.vo.User.UserGetInfoByIdVO;
import lombok.SneakyThrows;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description 认证业务层
 * @Author 翟玉龙
 * @Date 2024/6/21
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, User> implements AdminService {

    /**
     * 注入AdminMapper
     */
    private final AdminMapper adminMapper;
    private final StringRedisTemplate redisTemplate;

    public AdminServiceImpl(AdminMapper adminMapper, StringRedisTemplate redisTemplate) {
        this.adminMapper = adminMapper;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 初步登录检查
     * @param adminLoginDTO 登录参数
     * @return {@link Result }<{@link User }>
     */
    @SneakyThrows
    public Result<User> CheckLoginUser(AdminLoginDTO adminLoginDTO) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        Long count = adminMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getUsername, adminLoginDTO.getUsername()));
        if(count == 0) {
            return Result.error("用户不存在", null);
        }
        String entryPass = AESUtil.encrypt(adminLoginDTO.getPassword());
        queryWrapper
                .eq(User::getUsername, adminLoginDTO.getUsername())
                .eq(User::getPassword, entryPass);
        User user = adminMapper.selectOne(queryWrapper);
        if(user == null) {
            return Result.error("密码错误", null);
        }
        return Result.success("初步检查成功", user);
    }

    /**
     * 生成token
     */
    @SneakyThrows
    public Result<AdminLoginVO> genToken(User user) {
        // 生成token
        Map<String , Object> claims = new HashMap<>();
        // 存储基础信息
        claims.put("id", user.getId()); // 存储用户id
        claims.put("roleId", user.getRoleId()); // 存储用户角色id
        claims.put("username", user.getUsername());
        // 定制token
        String token = JwtUtil.genToken(claims);
        String key = "token" + user.getId() + "," + user.getRoleId();

        // 存储token到redis
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        operations.set(key , token, 2 , TimeUnit.HOURS);

        // Bean拷贝到UserGetInfoByIdVO
        UserGetInfoByIdVO userGetInfoByIdVO = BeanCopyUtils.copyBean(user, UserGetInfoByIdVO.class);
        // 封装返回类
        AdminLoginVO adminLoginVO = new AdminLoginVO(token, userGetInfoByIdVO);

        // 返回
        return Result.success("登录成功", adminLoginVO);
    }

    /**
     * 管理员登录接口
     * @param adminLoginDTO 登录参数
     * @return {@link Result }<{@link AdminLoginVO }>
     */
    @SneakyThrows
    @Override
    public Result<AdminLoginVO> loginAdmin(AdminLoginDTO adminLoginDTO) {
        Result<User> result = CheckLoginUser(adminLoginDTO);
        User user = result.getData();
        if(user == null) {
            return Result.error(result.getMessage(), null);
        }
        if(user.getRoleId() == 2) {
            return Result.error("该用户没有登录权限", null);
        }
        return genToken(user);
    }

    /**
     * 普通用户登录接口
     * @param adminLoginDTO 登录参数
     * @return {@link Result }<{@link AdminLoginVO }>
     */
    @SneakyThrows
    @Override
    public Result<AdminLoginVO> loginUser(AdminLoginDTO adminLoginDTO) {
        Result<User> result = CheckLoginUser(adminLoginDTO);
        User user = result.getData();
        if(user == null) {
            return Result.error(result.getMessage(), null);
        }
        if(user.getRoleId() == 1) {
            return Result.error("该用户没有登录权限", null);
        }
        return genToken(user);
    }

    /**
     * 退出登录
     * @return {@link Result }<{@link String }>
     */
    @Override
    public Result<String> logoutAdmin() {
        Integer id = CommonUtils.getLocalId();
        Integer roleId = CommonUtils.getLocalRoleId();
        String key = "token" + id + "," + roleId;
        redisTemplate.delete(key);
        return Result.success(CodeAndMessageEnum.SUCCESS_EXIT);
    }
}
